/*
 * Created by Joseph Bridgewater
 * Created on Jan 2, 2006
 * Copyright (C) Azureus Software, Inc, All Rights Reserved.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation; either version 2
 * of the License, or (at your option) any later version.
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 *
 */

package com.aelitis.azureus.core.peermanager.piecepicker;

import java.util.List;

import org.gudy.azureus2.core3.peer.PEPeer;
import org.gudy.azureus2.core3.peer.PEPiece;
import org.gudy.azureus2.core3.util.IndentWriter;

/**
 * @author MjrTom
 * 
 */

public interface PiecePicker {
    public static final int REQUEST_HINT_MAX_LIFE = 120 * 1000;

    public boolean hasDownloadablePiece();

    /**
     * @return long value indicated serial number of current count of changes to hasNeededUndonePiece. A method interesting in tracking changes can
     *         compare this with a locally stored value to determine if the hasNeededUndonePiece status has changed since the last check.
     */
    public long getNeededUndonePieceChange();

    public void addHavePiece(PEPeer peer, int pieceNumber);

    /**
     * This is called periodically by the peer control scheduler. It should not normally be called by other methods. It will update the global
     * availability if neccesary and then update the derived information
     */
    public void updateAvailability();

    public int[] getAvailability();

    public int getAvailability(final int pieceNumber);

    public float getMinAvailability();

    public int getMaxAvailability();

    public float getAvgAvail();

    public long getAvailWentBadTime();

    public float getMinAvailability(int fileIndex);

    public long getBytesUnavailable();

    public void allocateRequests();

    public boolean isInEndGameMode();

    public boolean hasEndGameModeBeenAbandoned();

    public void clearEndGameChunks();

    /**
     * adds all blocks in the piece to endGameModeChunks
     * 
     * @param pePiece
     */
    public void addEndGameChunks(final PEPiece pePiece);

    public void removeFromEndGameModeChunks(final int pieceNumber, final int offset);

    public int getNumberOfPieces();

    public int getNbPiecesDone();

    public void setForcePiece(int pieceNumber, boolean forced);

    public boolean isForcePiece(int pieceNumber);

    public void setGlobalRequestHint(int piece_number, int start_bytes, int byte_count);

    public int[] getGlobalRequestHint();

    public void setReverseBlockOrder(boolean is_reverse);

    public boolean getReverseBlockOrder();

    public void addRTAProvider(PieceRTAProvider shaper);

    public void removeRTAProvider(PieceRTAProvider shaper);

    public List getRTAProviders();

    public void addPriorityProvider(PiecePriorityProvider shaper);

    public void removePriorityProvider(PiecePriorityProvider shaper);

    public List getPriorityProviders();

    public void addListener(PiecePickerListener listener);

    public void removeListener(PiecePickerListener listener);

    public void destroy();

    public void generateEvidence(IndentWriter writer);

    public String getPieceString(int piece_number);
}
